package com.qingluan.widget;


import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import android.R.integer;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.support.v4.util.TimeUtils;
import android.text.format.Time;
import android.util.AttributeSet;
import android.util.Log;
import android.view.DragEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.qingluan.dd.R;

public class DragListView extends ListView implements OnScrollListener {
	//Statue arguments area
	public static final int RELEASING = 0;
	public static final int RELEASING_REFRESH_ABLE = 1;
	public static final int REFRESHING = 2 ;
	public static final int DONE = 3 ;
	
	public static final int UP_ABLE_RE = 4;
	public static final int UP_REFRE = 5;
	public static final int UP_RELEASE = 6;
	public static final int UP_DONE = 7;
	
	
	//个人爱好区域
	public static int QB ;
	public static final int UP_pu_tong = 11;
	public static final int UP_ao_jiao = 8;
	public static final int UP_mai_meng = 9;
	public static final int UP_jiao_teng = 10;
	
	//sign tag area
	private static boolean ISBACK = false;
	private static int NOW_STATE ; //for drag down.
	private static int UP_NOW_STATE ;//for drag up.
	private static boolean IS_BOTTOM = false;
	
	private static int UP_RELEASE_Y ; //for drag up
	private static int RELEASE_Y;
	
	private static int  STEP = 1;
	private static boolean isRefreshable ; // whether setting a listener for refresh;  
	//finger arguments area
	private int header_height;
	private int startY;
	private boolean isRecoreded = false;
	private int tail_height;
	
	//widget view area
	private LayoutInflater inflater;
	private LinearLayout header_view,tail_view;
	private TextView header_info,tail_text;
	private ImageView header_icon;
	private ProgressBar header_progress_bar, tailProgressBar;
	private RotateAnimation anim_rolate;
	//initialize interface
	private OnRefreshListener refreshListener ;
	private OnRefreshTailListener refreshTailListener;
	
	
	public DragListView(Context context) {
		super(context);
		initListView(context);
	}
	public DragListView(Context context,AttributeSet set){
		super(context,set);
		initListView(context);
	}
	
	
	
	//initialization ..
	//##################
	private void initListView(Context context) {
		// TODO Auto-generated method stub
		inflater = LayoutInflater.from(context) ;
		
		header_view = (LinearLayout)inflater.inflate(R.layout.menu_list_header,null);
		header_info = (TextView)header_view.findViewById(R.id.header_info);
		header_icon =  (ImageView)header_view.findViewById(R.id.header_icon);
		header_progress_bar = (ProgressBar)header_view.findViewById(R.id.header_progress);
		
		tail_view = (LinearLayout)inflater.inflate(R.layout.menu_list_la, null);
		tail_text = (TextView)tail_view.findViewById(R.id.la_info);
		tailProgressBar = (ProgressBar)tail_view.findViewById(R.id.tail_progress);
		
		//anim_rolate = AnimationUtils.loadAnimation(getContext(), R.anim.anim_rolate_turn);
		anim_rolate = new RotateAnimation(0, -180,  
	                RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
	                RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
		anim_rolate.setInterpolator(new LinearInterpolator());  
		anim_rolate.setDuration(250);  
		anim_rolate.setFillAfter(true);  
		
		
		//header area
		measureView(header_view);
		header_height = header_view.getMeasuredHeight();
		header_view.setPadding(0, -header_height, 0, 0);
		//header_view.invalidate();
		
		//tail area
		measureTailView(tail_view);
		tail_height = tail_view.getMeasuredHeight();
		tail_view.setPadding(0, 0, 0, -tail_height);
		
		addHeaderView(header_view); // add header_view to list
		addFooterView(tail_view); //add tail view to list
		
		setOnScrollListener(this);
		NOW_STATE = DONE;
		UP_NOW_STATE = UP_DONE;
		QB = UP_pu_tong;
		isRefreshable = false;
		
		
	}
	
	
	
	
	
	
	//drag listener...
	//############
	@Override
	public boolean onTouchEvent(MotionEvent ev){
		switch (ev.getAction()){
			case MotionEvent.ACTION_DOWN:
				if (isRecoreded == false){
					startY = (int)ev.getY();
					isRecoreded = true;
				}
				
				
				break;
			case MotionEvent.ACTION_UP:
				
				if (NOW_STATE != REFRESHING ){
					if (NOW_STATE == RELEASING_REFRESH_ABLE){
						NOW_STATE = REFRESHING;
						changeHeaderViewByState();
						onRefreshDoSomeThing();	
					}else if (NOW_STATE == RELEASING){
						NOW_STATE = DONE;
						changeHeaderViewByState();
					}
					RELEASE_Y = (int)(ev.getY() -startY);
				}
				/*
				 * ####################
				 */
				//drag up
				if (UP_NOW_STATE != DragListView.UP_REFRE){
					if (UP_NOW_STATE == DragListView.UP_ABLE_RE){
						UP_NOW_STATE = DragListView.UP_REFRE;
						UP_RELEASE_Y = (int)(startY - ev.getY());
						changeTailViewByState();
						onRefreshOnTail();
					}else if (UP_NOW_STATE == DragListView.UP_RELEASE){
						UP_NOW_STATE = UP_DONE;
						UP_RELEASE_Y = (int) (startY - ev.getY());
						changeTailViewByState();
					}
				}
				
				//state record 
				isRecoreded = false;
				break;
			case MotionEvent.ACTION_MOVE:
				int tempY = (int )ev.getY();

				Log.d("LOCATION_TEMP", "start Y :"+String.valueOf(startY));
				Log.d("LOCATION_TEMP", "Y :"+String.valueOf(tempY));
				if (!isRefreshable){
					isRecoreded = true;
					startY = tempY;
				}
				if (NOW_STATE != REFRESHING && isRecoreded && UP_NOW_STATE != UP_REFRE){
					
					/*
					 * ##############
					 * 
					 */
					//drag down area
					if(NOW_STATE == DragListView.RELEASING){
						
						if (tempY - startY >= header_height){
							NOW_STATE = DragListView.RELEASING_REFRESH_ABLE;
							changeHeaderViewByState();
						}else  if (tempY -startY <= 0){
							NOW_STATE = DragListView.DONE;
							changeHeaderViewByState();
						}
					}
					if (NOW_STATE== DragListView.RELEASING_REFRESH_ABLE){
						
						if (tempY-startY < header_height ){
							NOW_STATE = DragListView.RELEASING;
							ISBACK = true;
							changeHeaderViewByState();
						}
					}
					if (NOW_STATE == DONE){
						if (tempY - startY > 0){
							NOW_STATE = DragListView.RELEASING;
							changeHeaderViewByState();
						}
					}
					
					//drag up 
					/* ######################
					 *  this is for drag up ....
					 *  #####################
					 */
					if (UP_NOW_STATE == DragListView.UP_RELEASE){
						
						//个人爱好
						if (startY - tempY > tail_height/2 && startY -tempY <tail_height){
							QB = DragListView.UP_ao_jiao;
							changeTailViewByState();
						}
						
						if (startY - tempY >= tail_height){
							UP_NOW_STATE = DragListView.UP_ABLE_RE;
							changeTailViewByState();
						}else if (startY - tempY <= 0){
							UP_NOW_STATE = DragListView.UP_DONE;
							try{
								changeTailViewByState();
							}catch (IllegalArgumentException e) {
								e.printStackTrace();
								Log.d("illegalArgiumentsError", e.toString());
							}
						}
					}
					
					if (UP_NOW_STATE == DragListView.UP_ABLE_RE){
						
						if (startY - tempY > tail_height && startY -tempY < tail_height*2){
							QB = DragListView.UP_mai_meng;
							changeTailViewByState();
						}else {
							QB = DragListView.UP_jiao_teng;
							changeTailViewByState();
						}
						
						if (startY-tempY < tail_height){
							UP_NOW_STATE = DragListView.UP_RELEASE;
							changeTailViewByState();
						}
					}
					if (UP_NOW_STATE == DragListView.UP_DONE){
						if(startY - tempY > 0){
							UP_NOW_STATE = DragListView.UP_RELEASE;
							changeTailViewByState();
						}
					}
					
					if(tempY > startY){
						header_view.setPadding(0, (tempY -startY - header_height)/2, 0,0);
					}else {
						tail_view.setPadding(0, 0, 0,( tail_height+startY - tempY));
					}
				}
				break;
			default:
				break;
		}
		return super.onTouchEvent(ev);
	}
	
	
	//up control 
	//
	//#############
	private void changeTailViewByState() {
		// TODO Auto-generated method stub
		Log.d("LOCATION_TEMP","up state :" +String.valueOf(UP_NOW_STATE));
		if (IS_BOTTOM){
			switch (UP_NOW_STATE) {
			case UP_RELEASE:
				tail_text.setVisibility(View.VISIBLE);
				switch (QB) {
				case UP_ao_jiao:
					tail_text.setText("讨厌啦。。放开人家啦。。。");
					break;
				default:
					break;
				}
				
				break;
			case UP_ABLE_RE:
				switch (QB) {
				case UP_mai_meng:
					tail_text.setText("很痛啊，不要拉啦 T T。。。");
					break;
				case UP_jiao_teng:
					tail_text.setText("Q Q ..人家不理你啦 。。。");
					break;
				default:
					break;
				}
				break;
				
			case UP_REFRE:
				Log.d("LOCATION_TEMP","realese y :"+String.valueOf(UP_RELEASE_Y));
				final ScheduledExecutorService schedulor = Executors.newScheduledThreadPool(1);
				
				final Handler handler = new Handler(){
					
					@Override
					public void handleMessage(Message msg) {
						// TODO Auto-generated method stub
						super.handleMessage(msg);
						UP_RELEASE_Y -= 10;
						Log.d("LOCATION","now position : re"+String.valueOf(UP_RELEASE_Y));
						tail_view.setPadding(0, 0, 0, UP_RELEASE_Y );	
						tail_view.invalidate();
						
						if (UP_RELEASE_Y <= 0){
							schedulor.shutdownNow();
						}
					}
				};

				
				
				Runnable Ui = new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						Message msg = new Message();
						handler.sendMessage(msg);
					}
				};
				
				schedulor.scheduleAtFixedRate(Ui, 1, UP_RELEASE_Y*2500,TimeUnit.NANOSECONDS);
				
				//tail_view.setPadding(0, 0, 0, 0);
				tailProgressBar.setVisibility(View.VISIBLE);
				tail_text.setText("等待什么的 最讨厌了。。");
				break;
			case UP_DONE:
				final ScheduledExecutorService schedulorNew = Executors.newScheduledThreadPool(10);
				STEP = 10;
				final Handler handlerNew = new Handler(){
					
					@Override
					public void handleMessage(Message msg) {
						// TODO Auto-generated method stub
						super.handleMessage(msg);
						UP_RELEASE_Y -= msg.arg1;
						
						Log.d("LOCATION","now position : re"+String.valueOf(UP_RELEASE_Y));
						
						tail_view.setPadding(0, 0, 0, UP_RELEASE_Y );	
						tail_view.invalidate();
						
						if (UP_RELEASE_Y <= -tail_height){
							schedulorNew.shutdownNow();
						}
					}
				};

				
				
				Runnable UiNew = new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						Message msg = new Message();
						
						msg.arg1 = STEP;
						handlerNew.sendMessage(msg);
					}
				};
				
				schedulorNew.scheduleAtFixedRate(UiNew, 1, UP_RELEASE_Y *2500,TimeUnit.NANOSECONDS);
				
				//tail_view.setPadding(0, 0, 0, -tail_height);
				//tail_view.setPadding(0, 0, 0, -tail_height);
				tailProgressBar.setVisibility(View.GONE);
				tail_text.setText("唉。。唉！！ 要刷新么 0 0 ！");
				break;
			default:
				break;
			}
		}
	}
	
	
	
	
	public void setOnPlaceClickListener(){
		
	}
	
	/*
	 * 
	 * 
	 * 
	 * 
	 * 
	 */
	//do some thing on Refresh 
	public void onRefreshDoSomeThing() {
		// TODO Auto-generated method stub
		if (refreshListener != null ){
			NOW_STATE =  this.refreshListener.onRefresh();
			this.onRefreshComplete();
			//changeHeaderViewByState();
		}
	}
	private void onRefreshOnTail() {
		// TODO Auto-generated method stub
		if (refreshTailListener != null){
			UP_NOW_STATE = this.refreshTailListener.onRefresh();
			this.onRefreshTailCom();
		}
	}
	
	
	
	
	public void onRefreshTailCom(){
		UP_NOW_STATE = UP_DONE;
		changeTailViewByState();
	}
	
	public void onRefreshComplete() {  
        NOW_STATE = DONE;  
        changeHeaderViewByState();  
	}  

	private void changeHeaderViewByState() {
		Log.d("I_GET","state : "+String.valueOf(NOW_STATE));
		switch (NOW_STATE){
		case RELEASING:
			header_icon.setVisibility(View.VISIBLE);
			header_info.setVisibility(View.VISIBLE);
			header_info.setText("下拉刷新");
			if(ISBACK){
				header_icon.clearAnimation();
				header_icon.startAnimation(anim_rolate);
				ISBACK = false;
			}
			break;
		case RELEASING_REFRESH_ABLE:
			//header_progress_bar.setVisibility(View.VISIBLE);
			header_info.setText("松手开始刷新");
			header_icon.clearAnimation();
			
			header_icon.startAnimation(anim_rolate);
			break;
		
		case REFRESHING:
			/*
			final ScheduledExecutorService schedulorNew = Executors.newScheduledThreadPool(3);
			STEP = 12;
			final Handler handlerNew = new Handler(){
				
				@Override
				public void handleMessage(Message msg) {
					// TODO Auto-generated method stub
					super.handleMessage(msg);
					UP_RELEASE_Y -= msg.arg1;
					
					Log.d("LOCATION","now position : re"+String.valueOf(UP_RELEASE_Y));
					
					header_view.setPadding(0, RELEASE_Y, 0, 0 );	
					header_view.invalidate();
					
					if (RELEASE_Y <= 0){
						schedulorNew.shutdownNow();
					}
				}
			};

			
			
			Runnable UiNew = new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					Message msg = new Message();
					
					msg.arg1 = STEP;
					handlerNew.sendMessage(msg);
				}
			};
			
			schedulorNew.scheduleAtFixedRate(UiNew, 1, RELEASE_Y *1500,TimeUnit.NANOSECONDS);
			*/
			header_view.setPadding(0, 0, 0, 0);
			header_progress_bar.setVisibility(View.VISIBLE);
			header_info.setText("正在刷新");
			header_icon.setVisibility(View.GONE);
			break;
		case DONE:
			/*
			final ScheduledExecutorService schedulorO = Executors.newScheduledThreadPool(3);
			STEP = 10;
			final Handler handlerO= new Handler(){
				
				@Override
				public void handleMessage(Message msg) {
					// TODO Auto-generated method stub
					super.handleMessage(msg);
					RELEASE_Y -= msg.arg1;
					
					Log.d("LOCATION","now position : re"+String.valueOf(RELEASE_Y));
					
					header_view.setPadding(0, 0, 0, RELEASE_Y );	
					header_view.invalidate();
					
					if (RELEASE_Y <= -header_height){
						schedulorO.shutdownNow();
					}
				}
			};

			
			
			Runnable UiO = new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					Message msg = new Message();
					
					msg.arg1 = STEP;
					handlerO.sendMessage(msg);
				}
			};
			
			schedulorO.scheduleAtFixedRate(UiO, 1, RELEASE_Y *1500,TimeUnit.NANOSECONDS);
			
			*/
			header_view.setPadding(0, -header_height, 0, 0);
			header_progress_bar.setVisibility(View.GONE);
			header_info.setText("下拉刷新");
			header_icon.clearAnimation();
			break;
		default :
			break;
			
		}
		
	}
	/**
	 * set adapter
	 */
	public void setAdapter(ListAdapter adapter){
		super.setAdapter(adapter);
	}
	
	
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		// TODO Auto-generated method stub
		if (visibleItemCount + firstVisibleItem == totalItemCount){
			IS_BOTTOM =true;
		}else {
			IS_BOTTOM = false;
		}
		
	}
	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// TODO Auto-generated method stub
		
	}
	
	
	//set listener 
	public void setOnRefreshListener(OnRefreshListener refreshListener){
		this.refreshListener = refreshListener;
		isRefreshable = true;
	}
	
	public void setOnRefreshTailListener(OnRefreshTailListener refreshTailListener){
		this.refreshTailListener = refreshTailListener;
		isRefreshable =true;
	}
	
	
	
	
	//measure view
	public void measureView(View childView){
		ViewGroup.LayoutParams params = childView.getLayoutParams();
		if (params == null){
			params = new ViewGroup.LayoutParams(
					ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
		}
		
		int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, params.width);
		int LVHeight = params.height;
		int childHeightSpec;
		if (LVHeight > 0){
			childHeightSpec = MeasureSpec.makeMeasureSpec(LVHeight, MeasureSpec.EXACTLY);
		}else {
			childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
			
		}
		childView.measure(childWidthSpec, childHeightSpec);
	}
	
	public void measureTailView(View childView){
		ViewGroup.LayoutParams params = childView.getLayoutParams();
		if (params == null){
			params = new ViewGroup.LayoutParams(
					ViewGroup.LayoutParams.MATCH_PARENT, 
					ViewGroup.LayoutParams.WRAP_CONTENT);
		}
		int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, params.width);
		int LVHeight = params.height;
		int childHeightSpec;
		if (LVHeight > 0){
			childHeightSpec = MeasureSpec.makeMeasureSpec(LVHeight, MeasureSpec.EXACTLY);
		}else {
			childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
			
		}
		childView.measure(childWidthSpec, childHeightSpec);
	}
	
	
	
	
	
	
	public interface OnRefreshListener{
		public int onRefresh();
	}
	
	public interface OnRefreshTailListener{
		public int onRefresh();
	}
	
	public void ChangeStateHardWay(int state){
		DragListView.NOW_STATE = state;
	}

}
